class Observer {
    constructor(data) {
        this.walk(data);
    }
    walk(data){
        //判断data是否存在并且是对象
        if(!data || typeof data !== 'object'){
            return 
        }
        //遍历data对象调用defineReactive监听data的值
        Object.keys(data).forEach( key => {
            this.defineReactive(data,key,data[key])
        })
    }
    defineReactive(obj,key,val){
        let _this = this;
        //创建发布者,收集依赖
        let dep = new Dep()
        //此处调用是为了是多层对象也是也是响应式数据，因为对象下的属性仍是对象的话，是无法给其添加getter和setter属性
        //故递归调用给对象下的对象属性添加getter和setter,walk会判断是否是对象然后调用defineReactive。。。。
        this.walk(val);
        Object.defineProperty(obj,key,{
            enumerable:true,
            configurable:true,
            get(){
                //收集依赖
                Dep.target&&dep.addSubs(Dep.target)
                //此处需要使用val是因为如果使用obj[key]就出现递归调用，死循环造成堆栈溢出
                //进步的原因就是造成了闭包，没有被释放
                return val
            },
            set(newVal){
                //判断值是否改变
                if(newVal===obj[key]){
                    return
                };
                //改变就重新赋值
                val = newVal;
                /*
                *    此处调用同样是递归，如果是已存在的属性，原本的值非对象，重新赋值却是对象，
                *    before:name:'syk'; after:name:{'text':'syk'}此刻新属性作为对象是没有getter
                *    和setter方法的，所以调用walk给其添加geeter和setter方法
                */
               _this.walk(newVal);
                //数据更新时下发通知
               dep.notify();
            }
        })
    }
}